import 'package:flutter/material.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:ichinesereader/constants.dart';
import 'package:ichinesereader/controller/cache.dart';
import 'package:ichinesereader/controller/schooladmin.dart';
import 'package:ichinesereader/models/common/PropertyMessageResult.dart';
import 'package:ichinesereader/models/forms/forms.dart';
import 'package:ichinesereader/utils/StrUtil.dart';
import 'package:ichinesereader/utils/helper.dart';
import 'package:ichinesereader/widgets/layouts/customAppBar.dart';
import 'package:reactive_dropdown_search/reactive_dropdown_search.dart';
import 'package:reactive_forms/reactive_forms.dart';
import 'package:get/get.dart';
import 'package:ichinesereader/models/school/teacherCreateDto.dart';
import 'package:ichinesereader/models/school/teacherItem.dart';
import 'package:ichinesereader/models/school/teacherUpdateDto.dart';
import 'package:ichinesereader/service/user.dart';
import 'package:ichinesereader/utils/log.dart';

class DropdownModel {
  DropdownModel(this.id, this.text);

  String? id = "";
  String? text = "";

  @override
  String toString() {
    return "$text";
  }
}

// ignore: must_be_immutable
class AdminTeacherEditor extends StatelessWidget {
  AdminTeacherEditor({
    Key? key,
    this.teacherId,
  }) : super(key: key);

  String? teacherId;
  final UserServiceProvider _userServiceProvider = new UserServiceProvider();

  @override
  Widget build(BuildContext context) {
    Log.debug("build AdminTeacherEditor teacherId=${teacherId.toString()}");
    final SchoolAdminController controller = Get.find();
    var box = Hive.box('appconfig');
    bool isCreate = StrUtil.notHasValue(teacherId);
    List<DropdownModel> allTeachers = [];

    controller.classItemsWithoutAll.forEach((element) {
      allTeachers.add(DropdownModel(element.classId, element.className));
    });

    bool isSchoolAdmin = box.get(CacheManagerKey['nanhairole'].toString()) ==
        Constants.NanhaiRole_SchoolAdmin;

    // controller.fetchSchoolTeachers(); //打开老师列表的时候已经获取，可以去掉，减少此处调用
    TeacherDetailsEditFormModel formModel = new TeacherDetailsEditFormModel();
    TeacherDetailsNewFormModel newFormModel = new TeacherDetailsNewFormModel();
    FormGroup form = isCreate ? newFormModel.form : formModel.form;
    if (isCreate) {
      form
          .control("username")
          .setAsyncValidators([asyncValidatorUniqueUsername]);
      form.control("email").setAsyncValidators([_asyncValidatorUniqueEmail]);
    }

    void updateTeacher(TeacherUpdateDto dto) async {
      var response = await _userServiceProvider.updateTeacherDetails(
          dto.userName.toString(), dto);
      if (response.statusCode == 200) {
        showSnackMsg('Settings have been updated successfully.');
        // Get.snackbar('Message'.tr, 'Settings have been updated successfully'.tr,
        //     backgroundColor: Get.theme.primaryColor,
        //     colorText: Get.theme.primaryColorLight,
        //     snackPosition: SnackPosition.BOTTOM);
      } else {
        var result = propertyMessageResultFromJson(response.bodyString);
        showSnackMsg('${result.message?.message.toString()}');
        // Get.snackbar('Message'.tr, '${result.message?.message.toString()}'.tr,
        //     backgroundColor: Get.theme.primaryColor,
        //     colorText: Get.theme.primaryColorLight,
        //     snackPosition: SnackPosition.BOTTOM);
      }
      Future.delayed(const Duration(milliseconds: 2000), () {
        controller.fetchSchoolTeachers();
        //Get.offAndToNamed("/schooladmin/teachers");
      });
    }

    void createTeacher(TeacherCreateDto dto) async {
      var response = await _userServiceProvider.createTeacher(dto);
      if (response.statusCode == 200) {
        controller.fetchSchoolTeachers();
        showSnackMsg('Teacher has been created successfully');
        // Get.snackbar('Message'.tr, 'Teacher has been created successfully'.tr,
        //     backgroundColor: Get.theme.primaryColor,
        //     colorText: Get.theme.primaryColorLight,
        //     snackPosition: SnackPosition.BOTTOM);
      } else {
        var result = propertyMessageResultFromJson(response.bodyString);
        showSnackMsg('${result.message?.message.toString()}');
        // Get.snackbar('Message'.tr, '${result.message?.message.toString()}'.tr,
        //     backgroundColor: Get.theme.primaryColor,
        //     colorText: Get.theme.primaryColorLight,
        //     snackPosition: SnackPosition.BOTTOM);
      }
      Future.delayed(const Duration(milliseconds: 2000), () {
        Navigator.of(context).pop();
        //Get.offAndToNamed("/schooladmin/teachers");
      });
    }

    void _onUpdate() {
      Log.debug('Hello Reactive Forms!!!');
      Log.debug(form.value);
      if (!form.valid) {
        form.markAllAsTouched();
        return;
      }
      // FormControl<List<DropdownModel>> classIDsFormControl =
      //     form.control("classIds") as FormControl<List<DropdownModel>>;
      var classIdsDropdownModel =
          form.control("classIds").value as List<DropdownModel>;
      List<String> classIds = [];
      classIdsDropdownModel.forEach((e) => classIds.add(e.id.toString()));
      TeacherUpdateDto dto = new TeacherUpdateDto();
      dto.userName = form.control('username').value;
      dto.firstName = form.control('firstname').value;
      dto.lastName = form.control('lastname').value;
      dto.classId = classIds;
      updateTeacher(dto);
    }

    void _onCreate() {
      Log.debug("form.valid=${form.valid} form.value=${form.value}");
      if (!form.valid) {
        form.markAllAsTouched();
        return;
      }
      // FormControl<List<DropdownModel>> classIDsFormControl =
      //     form.control("classIds") as FormControl<List<DropdownModel>>;
      var classIdsDropdownModel =
          form.control("classIds").value as List<DropdownModel>;
      List<String> classIds = [];
      classIdsDropdownModel.forEach((e) => classIds.add(e.id.toString()));
      TeacherCreateDto dto = new TeacherCreateDto();
      dto.userName = form.control('username').value;
      dto.firstName = form.control('firstname').value;
      dto.lastName = form.control('lastname').value;
      // dto.classId = classIds;
      dto.email = form.control('email').value;
      dto.password = form.control('password').value;
      Log.debug(dto);
      createTeacher(dto);
    }

    _buildForm() {
      List<Widget> formWidget = [];

      bool teacherDropdownModelCompareFn(
          DropdownModel? item, DropdownModel? selectedItem) {
        Log.debug(
            "item=${item.toString()} selectedItem=${selectedItem.toString()}");
        return item != null &&
            selectedItem != null &&
            item.id == selectedItem.id;
      }

      formWidget.add(ReactiveTextField(
        formControlName: 'username',
        // validationMessages: (control) => {
        //   'unique': 'The user name is already used',
        // },
        validationMessages: {
          'unique': (_) => 'The user name is already used'.tr,
        },
        style: Theme.of(context).textTheme.displaySmall,
        textInputAction: TextInputAction.next,
        decoration: InputDecoration(
          alignLabelWithHint: true,
          labelText: 'User Name'.tr,
          labelStyle: Theme.of(context).textTheme.displaySmall,
        ),
        readOnly: !isCreate,
      ));
      formWidget.add(ReactiveTextField(
        formControlName: 'firstname',
        style: Theme.of(context).textTheme.displaySmall,
        textInputAction: TextInputAction.next,
        decoration: InputDecoration(
          alignLabelWithHint: true,
          labelText: 'First Name'.tr,
          labelStyle: Theme.of(context).textTheme.displaySmall,
        ),
      ));
      formWidget.add(ReactiveTextField(
        formControlName: 'lastname',
        style: Theme.of(context).textTheme.displaySmall,
        textInputAction: TextInputAction.next,
        decoration: InputDecoration(
          alignLabelWithHint: true,
          labelText: 'Last Name'.tr,
          labelStyle: Theme.of(context).textTheme.displaySmall,
        ),
      ));
      !isCreate
          ? formWidget.add(ReactiveDropdownSearchMultiSelection<DropdownModel,
              DropdownModel>(
              dropdownDecoratorProps: DropDownDecoratorProps(
                dropdownSearchDecoration: InputDecoration(
                  hintText: "Select class".tr,
                  labelText: "Class".tr,
                ),
              ),
              // decoration: const InputDecoration(
              //   hintText: "Select class",
              //   labelText: "Class",
              //   helperText: '',
              // ),
              //popupBackgroundColor: Colors.white,
              popupProps: PopupPropsMultiSelection.menu(
                  showSelectedItems: true, showSearchBox: true),
              formControlName: 'classIds',
              //mode: Mode.BOTTOM_SHEET,
              //showSelectedItems: true,
              compareFn: (item, selectedItem) =>
                  teacherDropdownModelCompareFn(item, selectedItem),
              filterFn: (user, filter) => true,
              items: allTeachers,
              //label: "Class",
              showClearButton: true,
              //showSearchBox: true,
              //maxHeight: 400,
            ))
          : Text('');
      isCreate
          ? formWidget.add(ReactiveTextField(
              formControlName: 'email',
              // validationMessages: (control) => {
              //   'unique': 'The email is already used'.tr,
              // },
              validationMessages: {
                'unique': (_) => 'The email is already used'.tr,
              },
              style: Theme.of(context).textTheme.displaySmall,
              textInputAction: TextInputAction.next,
              decoration: InputDecoration(
                alignLabelWithHint: true,
                labelText: 'Email'.tr,
                labelStyle: Theme.of(context).textTheme.displaySmall,
              ),
            ))
          : Text('');
      isCreate
          ? formWidget.add(ReactiveTextField(
              formControlName: 'password',
              style: Theme.of(context).textTheme.displaySmall,
              textInputAction: TextInputAction.next,
              decoration: InputDecoration(
                alignLabelWithHint: true,
                labelText: 'Password'.tr,
                labelStyle: Theme.of(context).textTheme.displaySmall,
              ),
              obscureText: true,
            ))
          : Text('');
      formWidget.add(SizedBox(
        height: 24,
      ));
      formWidget.add(Row(
        mainAxisAlignment: MainAxisAlignment.end,
        children: [
          ReactiveFormConsumer(
            builder: (context, form, child) {
              return ElevatedButton(
                  child: Text('Submit'.tr),
                  onPressed: isCreate ? _onCreate : _onUpdate);
            },
          ),
        ],
      ));
      return formWidget;
    }

    _buildObxForm() {
      return Obx(() {
        if (controller.classDetailsNew.value.classId == null) {}

        TeacherItem teacherItemModel;
        if (isCreate) {
          teacherItemModel = new TeacherItem();
        } else {
          teacherItemModel = controller.teacherItems
              .where((element) => element.objectId == teacherId)
              .first;
        }

        // List<String> selectedTeachers = [];
        // controller.classDetailsNew.value.teacherResps?.forEach((element) {
        //   selectedTeachers.add(element.userName.toString());
        // });
        form.control('username').value = teacherItemModel.userName;
        form.control('firstname').value = teacherItemModel.firstName;
        form.control('lastname').value = teacherItemModel.lastName;

        List<DropdownModel> selectedClassIds = [];
        teacherItemModel.classId?.forEach((classId) {
          Log.debug("forEach classId=$classId");
          var find = controller.classItemsWithoutAll
              .where((element) => element.classId == classId);
          if (find.isNotEmpty)
            selectedClassIds
                .add(DropdownModel(find.first.classId, find.first.className));
        });
        Log.debug("selectedClassIds=$selectedClassIds");
        form.control('classIds').value = selectedClassIds;
        return ReactiveForm(
            formGroup: form, child: Column(children: _buildForm()));
      });
    }

    return Scaffold(
      appBar: CustomAppBar(title: 'Teacher Settings'.tr),
      body: isSchoolAdmin
          ? SingleChildScrollView(
              primary: false,
              child: Padding(
                padding: const EdgeInsets.fromLTRB(36, 18, 36, 18),
                child: Column(
                  children: [
                    _buildObxForm(),
                  ],
                ),
              ),
            )
          : Text(''),
    );
  }

  // var formNewClass = formModel.formAdmin;
  // move to helper to be shared

  /// Async validator example that simulates a request to a server
  /// and validates if the email of the user is unique.
  // Future<Map<String, dynamic>?> _asyncValidatorUniqueUsername(
  //     AbstractControl<dynamic> control) async {
  //   final error = {'unique': false};
  //   String userName = control.value;
  //   Log.debug('_asyncValidatorUniqueUsername userName=$userName');
  //   final isAvailable = await _userServiceProvider.usernameAvailable(userName);
  //   Log.debug(
  //       '_asyncValidatorUniqueUsername userName=$userName usernameAvailable=$isAvailable');
  //   if (!isAvailable) {
  //     control.markAsTouched();
  //     return error;
  //   }
  //   return null;
  // }

  Future<Map<String, dynamic>?> _asyncValidatorUniqueEmail(
      AbstractControl<dynamic> control) async {
    final error = {'unique': false};
    String email = control.value;
    Log.debug('_asyncValidatorUniqueEmail email=$email');
    final isAvailable = await _userServiceProvider.emailAvailable(email);
    Log.debug(
        '_asyncValidatorUniqueEmail email=$email emailAvailable=$isAvailable');
    if (!isAvailable) {
      control.markAsTouched();
      return error;
    }
    return null;
  }
}
